Scapy è una potentissima libreria Python che permette di manipolare pacchetti di rete a tutti i livelli dello stack protocollare. A differenza di altri strumenti di analisi di rete, Scapy non si limita a catturare e visualizzare pacchetti, ma consente di costruire, modificare, inviare e ricevere pacchetti personalizzati con un controllo granulare su ogni singolo campo.
Questa caratteristica rende Scapy uno strumento fondamentale per:
Scapy opera principalmente in modalità interattiva (tramite shell Python) ma può essere utilizzato anche all’interno di script Python complessi. La sua filosofia di design si basa sulla semplicità d’uso combinata con una flessibilità estrema: con poche righe di codice è possibile creare pacchetti che richiederebbero centinaia di righe usando altre librerie.
Prima di procedere con l’analisi delle funzioni specifiche, è importante installare correttamente Scapy:
pip install scapy
Su sistemi Linux potrebbe essere necessario eseguire gli script con privilegi di amministratore (sudo) per accedere alle interfacce di rete a basso livello.
Ether è la classe di Scapy che rappresenta un frame Ethernet, ovvero l’unità di dati fondamentale del livello 2 (Data Link) del modello OSI. Quando parliamo di comunicazione in reti locali (LAN), parliamo essenzialmente di frame Ethernet che viaggiano da un dispositivo all’altro attraverso switch e bridge.
Un frame Ethernet è composto da diversi campi fondamentali:
Quando importiamo Ether da Scapy, otteniamo accesso a una classe che ci permette di creare e manipolare frame Ethernet con estrema facilità. Vediamo alcuni esempi pratici:
from scapy.all import Ether
# Creare un frame Ethernet basilare
frame = Ether()
Quando creiamo un oggetto Ether() senza parametri, Scapy imposta automaticamente alcuni valori di default. Possiamo visualizzare questi valori:
frame.show()
Output tipico:
###[ Ethernet ]###
dst = ff:ff:ff:ff:ff:ff (broadcast)
src = 00:00:00:00:00:00
type = 0x9000
Come possiamo osservare, il campo dst viene impostato automaticamente su ff:ff:ff:ff:ff:ff, che è l’indirizzo MAC broadcast (tutti i dispositivi della rete locale riceveranno questo frame).
Possiamo specificare manualmente i campi del frame Ethernet:
frame_custom = Ether(dst="aa:bb:cc:dd:ee:ff", src="11:22:33:44:55:66")
frame_custom.show()
Questo è particolarmente utile quando vogliamo:
La vera potenza di Ether emerge quando lo combiniamo con protocolli di livello superiore. Scapy utilizza l’operatore / per “impilare” i livelli protocollari:
from scapy.all import Ether, IP
# Creare un frame Ethernet che contiene un pacchetto IP
packet = Ether()/IP(dst="192.168.1.1")
packet.show()
In questo esempio, stiamo creando un frame Ethernet che incapsula un pacchetto IP. Scapy imposterà automaticamente il campo type di Ethernet a 0x0800 (IPv4) perché ha rilevato che stiamo trasportando un pacchetto IP.
Il campo type in Ethernet è cruciale perché dice al ricevente quale protocollo di livello superiore è contenuto nel payload. I valori più comuni sono:
Scapy gestisce automaticamente questo campo quando impiliamo i protocolli, ma possiamo anche impostarlo manualmente se necessario per scopi di testing.
ARP (Address Resolution Protocol) è uno dei protocolli fondamentali per il funzionamento delle reti locali. Il suo compito è risolvere il problema cruciale della traduzione tra indirizzi IP (livello 3, Network) e indirizzi MAC (livello 2, Data Link).
Immaginiamo questa situazione: il tuo computer (192.168.1.10) vuole inviare dati a un altro computer nella stessa rete locale (192.168.1.20). Il protocollo IP sa dove inviare i dati (all’indirizzo IP 192.168.1.20), ma a livello fisico, il frame Ethernet necessita dell’indirizzo MAC del destinatario. Come ottiene questo indirizzo MAC?
La risposta è: attraverso ARP!
Il processo ARP funziona in due fasi:
ARP Request (Richiesta broadcast):
Computer A: "Chi ha l'indirizzo IP 192.168.1.20? Per favore, rispondi con il tuo MAC address!"
Questa richiesta viene inviata in broadcast (a tutti i dispositivi della rete locale).
ARP Reply (Risposta unicast):
Computer B: "Io ho l'indirizzo IP 192.168.1.20 e il mio MAC address è aa:bb:cc:dd:ee:ff"
Solo il computer che possiede quell’indirizzo IP risponderà, inviando la sua risposta direttamente al richiedente.
Un pacchetto ARP contiene numerosi campi:
Vediamo come creare pacchetti ARP con Scapy:
from scapy.all import ARP
# Creare una ARP request basilare
arp_request = ARP()
arp_request.show()
Output tipico:
###[ ARP ]###
hwtype = 0x1 (Ethernet)
ptype = 0x800 (IPv4)
hwlen = 6
plen = 4
op = who-has (ARP request)
hwsrc = 00:00:00:00:00:00
psrc = 0.0.0.0
hwdst = 00:00:00:00:00:00
pdst = 0.0.0.0
Per creare una richiesta ARP funzionante per scoprire il MAC address di un dispositivo:
from scapy.all import Ether, ARP
# Definiamo l'IP target di cui vogliamo scoprire il MAC
target_ip = "192.168.1.1"
# Creiamo il frame Ethernet (broadcast)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# Creiamo la ARP request
arp = ARP(pdst=target_ip)
# Combiniamo i due livelli
packet = ether/arp
packet.show()
Questo pacchetto, quando inviato, chiederà: “Chi ha l’indirizzo IP 192.168.1.1? Rispondi al mio MAC address con il tuo!”
Possiamo anche creare manualmente una risposta ARP (utile per testing o per comprendere attacchi come ARP poisoning):
arp_reply = ARP(
op=2, # 2 = is-at (ARP reply)
hwsrc="aa:bb:cc:dd:ee:ff", # Il nostro MAC
psrc="192.168.1.100", # Il nostro IP
hwdst="11:22:33:44:55:66", # MAC del richiedente
pdst="192.168.1.50" # IP del richiedente
)
I sistemi operativi mantengono una ARP cache (tabella ARP) che memorizza le associazioni IP-MAC apprese. Questo evita di dover inviare una ARP request ogni volta che si comunica con lo stesso host.
Su Linux puoi visualizzare la cache ARP con:
arp -a
Su Windows:
arp -a
from scapy.all import Ether, ARP, srp
# Definiamo il range di IP da scansionare
target_range = "192.168.1.0/24"
# Creiamo il pacchetto ARP per l'intera subnet
arp = ARP(pdst=target_range)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp
# Inviamo e riceviamo (vedremo srp più avanti)
result = srp(packet, timeout=2, verbose=0)[0]
# Elaboriamo i risultati
for sent, received in result:
print(f"IP: {received.psrc} - MAC: {received.hwsrc}")
Questo script scansionerà tutti i 254 possibili indirizzi IP della subnet 192.168.1.0/24 e stamperà quali rispondono con il loro MAC address.
hexdump è una funzione di utilità di Scapy che permette di visualizzare il contenuto grezzo di un pacchetto in formato esadecimale e ASCII. Questa rappresentazione è fondamentale per comprendere cosa realmente viene trasmesso “sulla rete” a livello di byte.
Quando lavoriamo con protocolli di rete, è essenziale comprendere che tutti i dati viaggiano come sequenze di byte. La rappresentazione esadecimale ci permette di:
La funzione hexdump produce un output strutturato in questo modo:
0000 ff ff ff ff ff ff aa bb cc dd ee ff 08 06 00 01 ................
0010 08 00 06 04 00 01 aa bb cc dd ee ff c0 a8 01 0a ................
Analizziamo le tre sezioni:
.)from scapy.all import Ether, ARP, hexdump
# Creiamo un pacchetto
packet = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.1")
# Visualizziamo in formato esadecimale
hexdump(packet)
Output esempio:
0000 FF FF FF FF FF FF 00 00 00 00 00 00 08 06 00 01 ................
0010 08 00 06 04 00 01 00 00 00 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 C0 A8 01 01 ..........
Analizziamo il primo output byte per byte:
Offset 0000 - Header Ethernet:
FF FF FF FF FF FF: MAC di destinazione (broadcast)00 00 00 00 00 00: MAC sorgente (default di Scapy)08 06: EtherType (0x0806 = ARP)Offset 0010 - Header ARP:
00 01: Hardware type (Ethernet)08 00: Protocol type (IPv4)06: Hardware address length (6 byte per MAC)04: Protocol address length (4 byte per IPv4)00 01: Operation (1 = request)00 00 00 00 00 00: Hardware source (MAC mittente)00 00 00 00: Protocol source (IP mittente, primissimi byte)Offset 0020 - Continua ARP:
00 00 00 00 00 00: Hardware destination (MAC destinatario)C0 A8 01 01: Protocol destination (192.168.1.1 in esadecimale)Per comprendere meglio hexdump, è utile sapere come convertire tra rappresentazioni:
192 (decimale) = C0 (esadecimale)168 (decimale) = A8 (esadecimale)1 (decimale) = 01 (esadecimale)Quindi l’indirizzo IP 192.168.1.1 diventa C0 A8 01 01 in esadecimale.
È importante distinguere tra hexdump() e show():
# show() fornisce una vista "interpretata" del pacchetto
packet.show()
# Output:
# ###[ Ethernet ]###
# dst = ff:ff:ff:ff:ff:ff
# ...
# hexdump() mostra i byte grezzi
hexdump(packet)
# Output:
# 0000 FF FF FF FF FF FF ...
show() è utile per comprendere rapidamente la struttura logica del pacchetto, mentre hexdump() è essenziale per analisi approfondite e debugging a basso livello.
from scapy.all import Ether, ARP, IP, TCP, hexdump
# Creiamo un pacchetto complesso
complex_packet = Ether()/IP(dst="192.168.1.100")/TCP(dport=80, sport=12345)
print("=== Vista interpretata ===")
complex_packet.show()
print("\n=== Vista esadecimale ===")
hexdump(complex_packet)
Questo esempio mostra come hexdump sia particolarmente utile con pacchetti complessi multi-layer, permettendo di vedere esattamente come ogni livello protocollare è codificato in byte.
from scapy.all import sniff, hexdump
# Catturiamo un pacchetto dalla rete
packets = sniff(count=1)
# Visualizziamo in esadecimale
hexdump(packets[0])
Questo ci permette di analizzare il traffico reale della rete, vedendo esattamente cosa transita “sui fili”.
srp (Send and Receive Packets) è una delle funzioni più potenti di Scapy. Permette di inviare pacchetti a livello 2 (Data Link) e ricevere le risposte, tutto in un’unica operazione. La “p” finale sta per “packets” al plurale, perché srp può inviare e gestire molteplici pacchetti contemporaneamente.
Scapy offre diverse varianti della funzione send/receive:
srp è particolarmente importante quando lavoriamo con protocolli di livello 2 come ARP o quando vogliamo controllare direttamente gli indirizzi MAC.
from scapy.all import srp
answered, unanswered = srp(packet, timeout=2, verbose=True)
Vediamo i componenti:
srp restituisce una tupla di due elementi:
(answered, unanswered)
answered è un oggetto SRPResult contenente coppie di pacchetti:
for sent, received in answered:
print(f"Inviato: {sent.summary()}")
print(f"Ricevuto: {received.summary()}")
unanswered è un PacketList contenente i pacchetti senza risposta:
for packet in unanswered:
print(f"Nessuna risposta per: {packet.summary()}")
Vediamo un esempio pratico di network discovery utilizzando srp:
from scapy.all import Ether, ARP, srp
# Definiamo il range di IP da scansionare
target_ip = "192.168.1.0/24"
# Creiamo il pacchetto ARP
arp = ARP(pdst=target_ip)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp
# Inviamo i pacchetti e attendiamo le risposte
print("Scansione della rete in corso...")
answered, unanswered = srp(packet, timeout=2, verbose=0)
# Elaboriamo i risultati
print(f"\nDispositivi trovati: {len(answered)}\n")
print("IP\t\t\tMAC Address")
print("-" * 50)
for sent, received in answered:
print(f"{received.psrc}\t\t{received.hwsrc}")
print(f"\nHost che non hanno risposto: {len(unanswered)}")
srp invia 254 ARP requests (una per ogni IP nella /24) e ascolta le rispostesrp accetta numerosi parametri opzionali:
srp(
packet, # Pacchetto da inviare
timeout=2, # Timeout in secondi
verbose=True, # Mostra output dettagliato
iface=None, # Interfaccia di rete specifica
inter=0, # Intervallo tra pacchetti (secondi)
retry=0, # Numero di tentativi
multi=False # Accetta risposte multiple
)
Parametri importanti:
srp(packet, iface="eth0", timeout=2)
srp(packet, inter=0.1, timeout=2) # 100ms tra un pacchetto e l'altro
srp(packet, retry=2, timeout=1) # Prova 3 volte totali
srp(packet, multi=True, timeout=5)
Il parametro verbose controlla la quantità di informazioni mostrate:
# Verbose completo (default)
srp(packet, verbose=True)
# Output:
# Begin emission:
# Finished sending 1 packets.
# Received 5 packets, got 1 answers, remaining 0 packets
# Nessun output
srp(packet, verbose=0)
# Silenzioso, utile in script automatici
# Output numerico
srp(packet, verbose=2)
# Mostra anche i pacchetti individuali
Quando si lavora con srp, è importante sapere quale interfaccia di rete si sta usando:
from scapy.all import get_if_list, conf
# Elenco di tutte le interfacce disponibili
print(get_if_list())
# Interfaccia di default
print(conf.iface)
# Specificare manualmente l'interfaccia
srp(packet, iface="wlan0", timeout=2)
from scapy.all import Ether, ARP, srp
def check_duplicate_ip(target_ip):
"""
Verifica se un IP è usato da più dispositivi (IP conflict)
"""
# Creiamo una ARP request
arp = ARP(pdst=target_ip)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp
# Inviamo e riceviamo multiple risposte
answered, _ = srp(packet, timeout=2, multi=True, verbose=0)
if len(answered) > 1:
print(f"ATTENZIONE: IP {target_ip} è usato da più dispositivi!")
for sent, received in answered:
print(f" - MAC: {received.hwsrc}")
elif len(answered) == 1:
print(f"IP {target_ip} è usato da: {answered[0][1].hwsrc}")
else:
print(f"IP {target_ip} non risponde")
# Test
check_duplicate_ip("192.168.1.1")
from scapy.all import Ether, ARP, srp
import time
def advanced_network_scan(network_range):
"""
Scansione di rete con statistiche dettagliate
"""
# Preparazione
arp = ARP(pdst=network_range)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp
# Statistiche
start_time = time.time()
# Esecuzione scan
answered, unanswered = srp(
packet,
timeout=3,
verbose=0,
inter=0.05 # 50ms tra pacchetti per non saturare la rete
)
end_time = time.time()
# Risultati
print("=" * 60)
print("NETWORK SCAN REPORT")
print("=" * 60)
print(f"Range scansionato: {network_range}")
print(f"Tempo di esecuzione: {end_time - start_time:.2f} secondi")
print(f"Host attivi: {len(answered)}")
print(f"Host non raggiungibili: {len(unanswered)}")
print("\n" + "=" * 60)
print(f"{'IP ADDRESS':<20} {'MAC ADDRESS':<20} {'VENDOR'}")
print("=" * 60)
for sent, received in answered:
# Puoi integrare lookup del vendor dal MAC
print(f"{received.psrc:<20} {received.hwsrc:<20}")
print("=" * 60)
return answered, unanswered
# Utilizzo
results = advanced_network_scan("192.168.1.0/24")
È importante distinguere tra srp() (send and receive) e sendp() (solo send):
from scapy.all import sendp, srp
# sendp() - Solo invio, nessuna ricezione
sendp(packet, iface="eth0")
# Utile per: generazione di traffico, DoS testing (etico), simulazioni
# srp() - Invio E ricezione
answered, unanswered = srp(packet, iface="eth0", timeout=2)
# Utile per: discovery, probing, testing con verifica di risposta
Timeout adeguato: Imposta un timeout ragionevole in base alla dimensione della rete
# Rete piccola (< 50 host)
srp(packet, timeout=1)
# Rete media (50-200 host)
srp(packet, timeout=2)
# Rete grande (> 200 host)
srp(packet, timeout=3)
Rate limiting: Non saturare la rete con troppi pacchetti simultanei
srp(packet, inter=0.1) # 10 pacchetti/secondo
Gestione errori: Sempre gestire eccezioni in ambiente di produzione
try:
answered, unanswered = srp(packet, timeout=2, verbose=0)
except PermissionError:
print("Errore: sono necessari privilegi di amministratore")
except Exception as e:
print(f"Errore durante l'invio: {e}")
Interfaccia specifica: In sistemi con più interfacce, specifica quale usare
srp(packet, iface="eth0", timeout=2)
Mettiamo insieme tutto quello che abbiamo imparato in uno script completo e commentato:
#!/usr/bin/env python3
"""
Script di Network Discovery e Analysis
Utilizza Scapy per scoprire e analizzare host in una rete locale
"""
from scapy.all import Ether, ARP, srp, hexdump
import sys
def discover_network(target_range):
"""
Esegue una scansione ARP della rete e visualizza risultati dettagliati
Args:
target_range (str): Range IP in notazione CIDR (es. "192.168.1.0/24")
Returns:
tuple: (answered, unanswered) - risultati della scansione
"""
print(f"\n{'=' * 70}")
print(f"SCANSIONE RETE: {target_range}")
print(f"{'=' * 70}\n")
# FASE 1: Costruzione del pacchetto
print("[FASE 1] Costruzione pacchetto ARP...")
# Layer 2: Frame Ethernet (broadcast)
ether_layer = Ether(dst="ff:ff:ff:ff:ff:ff")
# Layer ARP: Request per il range specificato
arp_layer = ARP(pdst=target_range)
# Combinazione dei layer
packet = ether_layer / arp_layer
# Visualizzazione struttura pacchetto
print("\nStruttura del pacchetto:")
packet.show()
# Visualizzazione esadecimale
print("\nRappresentazione esadecimale:")
hexdump(packet)
# FASE 2: Invio e ricezione
print(f"\n[FASE 2] Invio pacchetti e ascolto risposte...")
print(f"Timeout: 3 secondi")
print(f"Intervallo tra pacchetti: 0.1 secondi\n")
try:
answered, unanswered = srp(
packet,
timeout=3,
verbose=1,
inter=0.1
)
except PermissionError:
print("\n[ERRORE] Sono richiesti privilegi di amministratore!")
print("Esegui lo script con: sudo python3 script.py")
sys.exit(1)
except Exception as e:
print(f"\n[ERRORE] Si è verificato un errore: {e}")
sys.exit(1)
# FASE 3: Analisi risultati
print(f"\n{'=' * 70}")
print("[FASE 3] RISULTATI SCANSIONE")
print(f"{'=' * 70}\n")
print(f"Host che hanno risposto: {len(answered)}")
print(f"Host non raggiungibili: {len(unanswered)}")
if answered:
print(f"\n{'IP ADDRESS':<20} {'MAC ADDRESS':<20} {'STATUS'}")
print("-" * 60)
for sent, received in answered:
print(f"{received.psrc:<20} {received.hwsrc:<20} ATTIVO")
# Analisi dettagliata del primo host trovato
if received == answered[0][1]:
print(f"\n{'=' * 70}")
print("ANALISI DETTAGLIATA PRIMO HOST")
print(f"{'=' * 70}")
print("\nPacchetto ricevuto:")
received.show()
print("\nDati grezzi (hexdump):")
hexdump(received)
else:
print("\nNessun host ha risposto alla scansione!")
return answered, unanswered
def analyze_single_host(ip_address):
"""
Analizza un singolo host specifico
Args:
ip_address (str): Indirizzo IP dell'host da analizzare
"""
print(f"\n{'=' * 70}")
print(f"ANALISI HOST: {ip_address}")
print(f"{'=' * 70}\n")
# Costruzione pacchetto per singolo host
packet = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip_address)
# Invio con possibilità di risposte multiple
answered, unanswered = srp(
packet,
timeout=2,
verbose=0,
multi=True # Permette di rilevare IP duplicati
)
if not answered:
print(f"L'host {ip_address} non ha risposto")
return
if len(answered) > 1:
print(f"ATTENZIONE: Rilevati {len(answered)} dispositivi con lo stesso IP!")
print("Possibile conflitto di indirizzi IP\n")
for idx, (sent, received) in enumerate(answered, 1):
print(f"Risposta #{idx}:")
print(f" IP: {received.psrc}")
print(f" MAC: {received.hwsrc}")
print(f" Tempo di risposta: {received.time - sent.sent_time:.6f}s")
print()
def main():
"""
Funzione principale
"""
# Configurazione
network_range = "192.168.1.0/24" # Modifica secondo la tua rete
print("""
╔═══════════════════════════════════════════════════════════════╗
║ SCAPY NETWORK DISCOVERY & ANALYSIS TOOL ║
║ ║
║ Questo script dimostra l'uso di: ║
║ - Ether: Costruzione frame Ethernet ║
║ - ARP: Address Resolution Protocol ║
║ - srp: Send and Receive Packets (Layer 2) ║
║ - hexdump: Visualizzazione esadecimale ║
╚═══════════════════════════════════════════════════════════════╝
""")
# Esegui scansione completa
answered, unanswered = discover_network(network_range)
# Se ci sono host attivi, analizza il primo in dettaglio
if answered:
first_host_ip = answered[0][1].psrc
input(f"\nPremi INVIO per analizzare in dettaglio l'host {first_host_ip}...")
analyze_single_host(first_host_ip)
print(f"\n{'=' * 70}")
print("SCANSIONE COMPLETATA")
print(f"{'=' * 70}\n")
if __name__ == "__main__":
main()
Scapy è uno strumento estremamente potente che permette di manipolare il traffico di rete a basso livello. Con questo potere viene la responsabilità di usarlo eticamente e legalmente.
✅ Usi legittimi:
❌ Usi illegali:
Obiettivo: Scoprire tutti i dispositivi nella tua rete locale
# Completa il codice
from scapy.all import Ether, ARP, srp
# TODO: Definisci il range IP della tua rete
target = "___.___.___.___ /___"
# TODO: Costruisci il pacchetto ARP
packet = ___
# TODO: Invia e ricevi
answered, unanswered = ___
# TODO: Stampa i risultati
for ___, ___ in answered:
print(f"IP: ___ - MAC: ___")
Obiettivo: Creare un pacchetto e analizzare la sua struttura esadecimale
from scapy.all import Ether, ARP, hexdump
# TODO: Crea un pacchetto ARP request per 192.168.1.1
packet = ___
# TODO: Visualizza il pacchetto in formato strutturato
___
# TODO: Visualizza il pacchetto in formato esadecimale
___
# TODO: Identifica manualmente nel hexdump:
# - Dove inizia l'indirizzo MAC di destinazione?
# - Dove si trova il campo 'operation' di ARP?
# - Dove è codificato l'indirizzo IP 192.168.1.1?
Obiettivo: Implementare un sistema di rilevamento conflitti IP
from scapy.all import Ether, ARP, srp
def find_duplicate_ips(network_range):
"""
TODO: Implementa una funzione che:
1. Scansiona il network_range
2. Identifica IP usati da più dispositivi
3. Stampa un report dei conflitti trovati
"""
pass
# Test
find_duplicate_ips("192.168.1.0/24")
Obiettivo: Creare uno script che genera statistiche di rete
from scapy.all import Ether, ARP, srp
import time
def network_statistics(network_range):
"""
TODO: Implementa uno script che calcola:
- Tempo medio di risposta degli host
- Percentuale di host attivi vs totali possibili
- Lista vendor dei MAC address (ricerca online)
- Grafico della distribuzione IP
"""
pass
Sintomo: Errore quando si cerca di inviare pacchetti
Soluzione:
# Linux/Mac
sudo python3 script.py
# Windows
# Esegui il terminale come amministratore
Sintomo: Python non trova il modulo Scapy
Soluzione:
pip install scapy
# oppure
pip3 install scapy
Possibili cause:
Soluzione:
from scapy.all import get_if_list, conf
# Verifica interfacce disponibili
print(get_if_list())
# Specifica l'interfaccia corretta
srp(packet, iface="eth0", timeout=3)
Causa: Interfaccia di rete in modalità promiscua non supportata o virtualizata
Soluzione: Verifica le impostazioni della scheda di rete virtuale se stai usando VM
In questa guida abbiamo esplorato in profondità quattro componenti fondamentali di Scapy:
Padroneggiare questi concetti ti permette di:
Scapy è uno strumento che cresce con te: più lo usi, più scopri le sue potenzialità. Inizia con esempi semplici, sperimenta in ambienti sicuri, e gradualmente costruisci script sempre più complessi.
Ricorda: con grande potere viene grande responsabilità. Usa sempre Scapy in modo etico e legale.
from scapy.all import Ether, ARP, hexdump, srp
# Broadcast
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# Unicast
ether = Ether(dst="aa:bb:cc:dd:ee:ff", src="11:22:33:44:55:66")
# ARP Request
arp = ARP(pdst="192.168.1.1")
# ARP Reply
arp = ARP(op=2, hwsrc="aa:bb:cc:dd:ee:ff", psrc="192.168.1.100")
# Send and Receive (Layer 2)
answered, unanswered = srp(packet, timeout=2, verbose=0)
# Vista strutturata
packet.show()
# Vista esadecimale
hexdump(packet)
for sent, received in answered:
print(f"IP: {received.psrc}, MAC: {received.hwsrc}")
Versione: 1.0
Ultima modifica: Gennaio 2025
Autore: Guida didattica per studenti ITI e Universitari
Licenza: Materiale educativo - Uso libero per scopi didattici